package com.cw.part3.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Random;
import java.util.UUID;

@Service
public class OrderService {
    //商品详情
    private static HashMap<String, Integer> product = new HashMap();
    //订单表
    private static HashMap<String, String> orders = new HashMap();
    //库存表
    private static HashMap<String, Integer> stock = new HashMap();

    //在初始化当前类对象时，就会加载下面的静态代码块(类似于数据的初始化）
    static {
        //123 指的是 参与秒杀活动的 商品的编号
        product.put("123", 500);
        stock.put("123", 500);
    }

    public String orderInfo(String productId) {
        return "限量抢购商品XXX共" + product.get(productId) + ",现在成功下单" + orders.size()
                + ",剩余库存" + stock.get(productId) + "件";
    }


    /**
     * 下单
     */
    public String publishOrder(String productId) {
        if (stock.get(productId) == 0) {
            return "活动已经结束了";
            //已近买完了
        } else {
            //还没有卖完
            try {
                //模拟操作数据库
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //订单数 +1
            orders.put(UUID.randomUUID() + "", productId);
            //库存数 - 1
            stock.put(productId, stock.get(productId) - 1);
        }
        return orderInfo(productId);
    }

    /**
     * 下单的第2种方式： 方法的线程同步。
     */
    public synchronized String publishOrderBySynchronized(String productId) {
        if (stock.get(productId) == 0) {
            return "活动已经结束了";
            //已近买完了
        } else {
            //还没有卖完
            try {
                //模拟操作数据库
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            orders.put(UUID.randomUUID() + "", productId);
            stock.put(productId, stock.get(productId) - 1);
        }
        return orderInfo(productId);
    }


    @Autowired
    private RedisLock redisLock;

    public String publishOrderByRedis(String productId) {
        //假设访问这个方法，需要时间进入
        String value = System.currentTimeMillis()+ "";
        /**
         * redis加锁.
         *  同一时间（同时：同一最小时间单位）
         */

        // ---当同时进入到下面这行代码，进行执行时  key=123 ; value:123456789
        if (!redisLock.lock1(productId, value)) {//被锁住的key-value ： 123- 时间戳（2019年9月23日11:12:02:120
            //系统繁忙，请稍后再试
            throw new RuntimeException("系统繁忙，请稍后再试");
        }


        //##############################业务逻辑#################################//
        if (stock.get(productId) == 0) {
            return "活动已经结束了";
            //已近买完了
        } else {
//            try {
//                //模拟操作数据库
//                Thread.sleep(10);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            orders.put(UUID.randomUUID().toString(), productId);//将抢到的商品 保存到 订单容器列表中
            stock.put(productId, stock.get(productId) - 1); // 将当前被抢到并下单成功后的商品，从库存中减1
        }
        //##############################业务逻辑#################################//



        /**
         * redis解锁
         */
        redisLock.unlock(productId, value);
        return orderInfo(productId);
    }
}
